Omakase RuboCop, Brakeman, Ruby 3.1+, allow_browser, rate_limit, and more | This Week in Rails
気になったやつだけメモしよう
.github/workflows/ci.yml
--skip-ci オプションをつけると設定ファイルの生成をスキップできる
たしかXのPOSTで見かけたんだよな
Kredis は Keyed Redis の略
Kredis (Keyed Redis) encapsulates higher-level types and data structures around a single key, so you can interact with them as coherent objects rather than isolated procedural commands.
高レベルの型とデータ構造をカプセル化してくれる
Redisで扱えるデータ構造には限りがあって、Rubyのオブジェクトをそのまま扱うことは本来できない ので、何らかの方法で変換をかますなどしてやりくりしている
この Kredis を使うと、そういった変換を上手にやってくれてRubyのオブジェクトのまま扱える
という認識をtanakenはしました
code:サンプルコード.rb
decimal = Kredis.decimal "mydecimal" # accuracy!
decimal.value = "%.47f" % (1.0 / 10)
# => SET mydecimal "0.10000000000000000555111512312578270211815834045"
BigDecimal("0.10000000000000000555111512312578270211815834045e0") == decimal.value
# => GET mydecimal
"mydecimal" という key で "%.47f" % (1.0 / 10) の計算結果を Redis に格納し、
Kredis.decimal("mydecimal").value で Redis からデータを取得すると同時に BigDecimal のオブジェクトに変換してくれている
で、この Kredis の limiter というタイプをつかって、コントローラーのレートリミットを実装できるようにしたよ、というのがこのプルリク
code:サンプルコード.rb
limiter = Kredis.limiter "mylimit", limit: 3, expires_in: 5.seconds
0 == limiter.value # => GET "limiter"
limiter.poke # => SET limiter 0 NX + INCRBY limiter 1
limiter.poke # => SET limiter 0 NX + INCRBY limiter 1
limiter.poke # => SET limiter 0 NX + INCRBY limiter 1
false == limiter.exceeded? # => GET "limiter"
limiter.poke # => SET limiter 0 NX + INCRBY limiter 1
true == limiter.exceeded? # => GET "limiter"
sleep 6
limiter.poke # => SET limiter 0 NX + INCRBY limiter 1
limiter.poke # => SET limiter 0 NX + INCRBY limiter 1
limiter.poke # => SET limiter 0 NX + INCRBY limiter 1
false == limiter.exceeded? # => GET "limiter"
コントローラーでの実装例
code:サンプルコードを一部改行.rb
class SessionsController < ApplicationController
rate_limit to: 10, within: 3.minutes, only: :create
end
class SignupsController < ApplicationController
rate_limit to: 1000,
within: 10.seconds,
by: -> { request.domain },
with: -> { redirect_to busy_controller_url, alert: "Too many signups!" },
only: :new
end
このプルリクの説明によると、これまではRailsのメジャーバージョンアップのときに、EOLになったRubyのバージョンとの互換性を削除する、というポリシーだったらしい(そうなんだ)
この方針を変えたほうが良いという提案をしている
理由は次のとおり:
EOLになったRubyバージョンとの互換性を長期間維持しなければならない場合がある
Railsのメジャーバージョンアップの際に、複数のRubyバージョンとの互換性を一気に削除しなければならない場合がある
Rails ver N -> N + 1 の間に、複数のRubyバージョンがEOLを迎えた場合かな